<?php
namespace app\job;

use think\queue\Job;
use app\model\SeckillActivity;
use app\model\Order;
use app\model\SeckillOrder;
use think\facade\Db;
use think\facade\Cache as CacheFacade;

class SeckillJob
{
    public function fire(Job $job, $data)
    {
        $userId = $data['user_id'];
        $activityId = $data['activity_id'];

        try {
            Db::startTrans();

            // 使用乐观锁减少库存
            $activity = SeckillActivity::where('id', $activityId)
                ->where('stock', '>', 0)
                ->lock(true)
                ->find();

            if (!$activity) {
                throw new \Exception('活动已结束');
            }

            // 再次检查用户是否已经参与过
            if (SeckillOrder::where(['user_id' => $userId, 'activity_id' => $activityId])->find()) {
                throw new \Exception('您已经参与过该活动');
            }

            // 减少库存
            $activity->stock = $activity->stock - 1;
            if (!$activity->save()) {
                throw new \Exception('库存减少失败');
            }

            // 创建订单
            $orderNo = 'SK' . date('YmdHis') . str_pad($userId, 6, '0', STR_PAD_LEFT) . rand(100, 999);
            $order = Order::create([
                'order_no' => $orderNo,
                'user_id' => $userId,
                'goods_id' => $activity->goods_id,
                'price' => $activity->price,
                'status' => 0,
                'create_time' => date('Y-m-d H:i:s')
            ]);

            // 创建秒杀订单
            SeckillOrder::create([
                'user_id' => $userId,
                'order_id' => $order->id,
                'goods_id' => $activity->goods_id,
                'activity_id' => $activityId,
                'order_no' => $orderNo
            ]);

            // 更新商品库存
            Db::name('goods')
                ->where('id', $activity->goods_id)
                ->where('stock', '>', 0)
                ->dec('stock', 1);

            Db::commit();

            // 更新缓存中的库存
            $stockKey = "seckill:stock:{$activityId}";
            $cacheStock = CacheFacade::get($stockKey);
            if ($cacheStock !== false) {
                CacheFacade::set($stockKey, max(0, $activity->stock));
            }

            // 抢购成功，可以发送通知等
            \think\facade\Log::info('用户[' . $userId . ']秒杀活动[' . $activityId . ']成功，订单号：' . $orderNo);

        } catch (\Exception $e) {
            Db::rollback();
            // 记录失败日志
            \think\facade\Log::error('秒杀失败: ' . $e->getMessage() . ' 用户ID: ' . $userId . ' 活动ID: ' . $activityId);
            
            // 如果是库存不足导致的失败，更新缓存
            if (strpos($e->getMessage(), '库存') !== false) {
                $stockKey = "seckill:stock:{$activityId}";
                CacheFacade::set($stockKey, 0);
            }
        }
        
        // 清除用户锁
        $lockKey = "seckill:user:{$userId}:activity:{$activityId}";
        CacheFacade::delete($lockKey);

        $job->delete();
    }

    public function failed($data)
    {
        // 任务失败处理
        \think\facade\Log::error('秒杀任务失败: ' . json_encode($data));
    }
}